package cn.yh.nft.turbo.notice.facade;

import cn.hutool.core.util.RandomUtil;
import cn.yh.nft.turbo.api.notice.response.NoticeResponse;
import cn.yh.nft.turbo.api.notice.service.NoticeFacadeService;
import cn.yh.nft.turbo.base.exception.SystemException;
import cn.yh.nft.turbo.limiter.SlidingWindowRateLimiter;
import cn.yh.nft.turbo.notice.domain.constant.NoticeState;
import cn.yh.nft.turbo.notice.domain.entity.Notice;
import cn.yh.nft.turbo.notice.domain.service.NoticeService;
import cn.yh.nft.turbo.rpc.facade.Facade;
import cn.yh.nft.turbo.sms.response.SmsSendResponse;
import cn.yh.nft.turbo.sms.service.SmsService;
import com.alibaba.fastjson2.JSON;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.Date;
import java.util.concurrent.TimeUnit;

import static cn.yh.nft.turbo.api.notice.constant.NoticeConstant.CAPTCHA_KEY_PREFIX;
import static cn.yh.nft.turbo.base.exception.BizErrorCode.SEND_NOTICE_DUPLICATED;

/**
 * @ClassName: NoticeFacadeServiceImpl
 * @Author: 草莓爱上啵啵
 */

@DubboService(version = "1.0.0")
public class NoticeFacadeServiceImpl implements NoticeFacadeService {

    /**
     * 限流的实现类注入
     */
    @Autowired
    private SlidingWindowRateLimiter slidingWindowRateLimiter;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private NoticeService noticeService;


    @Autowired
    private SmsService smsService;



    /**
     * 生成并发送短信验证码
     * @param telephone
     * @return
     */
    @Facade
    @Override
    public NoticeResponse generateAndSmsCaptcha(String telephone) {

        //限流-滑动窗口
        Boolean success = slidingWindowRateLimiter.tryAcquire(telephone, 1, 60);

        if (!success){
            throw new SystemException(SEND_NOTICE_DUPLICATED);
        }

        //生成验证码，保证在3分钟之内的验证码发送的是同一个
        String captcha = "";
        //先从redis当中查询是否保存有验证码
        captcha = redisTemplate.opsForValue().get(CAPTCHA_KEY_PREFIX + telephone);
        //验证码为null并且为"",表示该手机号对应的redis中不存在验证码，重新生成一下
        if (StringUtils.isEmpty(captcha)){
            captcha = RandomUtil.randomNumbers(4);
        }
        //将验证码存入redis中
        redisTemplate.opsForValue().set(CAPTCHA_KEY_PREFIX + telephone, captcha, 5, TimeUnit.MINUTES);

        //保存验证码
        Notice notice = noticeService.saveCaptcha(telephone, captcha);


        //发送短信
        Thread.ofVirtual().start(() -> {
            SmsSendResponse result = smsService.sendMsg(notice.getTargetAddress(), notice.getNoticeContent());
            if (result.getSuccess()){
                notice.setState(NoticeState.SUCCESS);
                notice.setSendSuccessTime(new Date());
                noticeService.updateById(notice);
            } else {
                notice.setState(NoticeState.FAILED);
                notice.addExtendInfo("executeResult", JSON.toJSONString(result));
                noticeService.updateById(notice);
            }
        });

        return new NoticeResponse.Builder().setSuccess(true).build();
    }
}
